package com.neusoft.liduan.d0927;

import java.awt.Point;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.junit.Test;

public class 反射 {
	/*	反射
	 * 		就相当是一个类的映射
	 * 		先有方法对象，再告诉这个方法对象属于哪个类的对象
	 * 		Class：类的模板类，用于保存类的所有信息，比如类的方法、属性、构造方法、父类、接口、注解等
	 * 			newInstance()：通过调用类的无参构造方法，创建对象
	 * 			getDeclaredField(name)：根据name获取属性对象，可以获取私有，但不能获取父类中
	 * 			getField(name)：根据name获取属性对象，不可以获取私有，但能获取父类中
	 *			
	 *			getConstructor(parameterTypes)：获取匹配的构造方法，parameterTypes形参列表
	 *			getConstructors()：获取所有的构造方法
	 *		Field：表示类中的属性
	 *			get(Object obj) ：该属性是由obj对象调用
	 *			set(Object obj, value)：设置obj对象的属性的值为value
	 *			getName()：获取属性的名称
	 *			setAccessible(boolean)：设置访问权限
	 *
	 *		Method：表示类中的方法
	 *			
	 *		Constructor：表示类中的构造方法
	 *			newInstance(Object... initargs) 
	 *			
	 * 	正常的类创建使用过程
	 * 		先有类再有对象，然后通过对象去调用属性和方法
	 */
	@Test
	public void t1() {
//		Chess c = new Chess("che", new Point(1,1), 0);
//		c.setName("ma");//先有对象，再调用方法
////		c.draw(null, null);
//		System.out.println(c);
		
		//学好反射可以通过字符串来创建类的对象及方法的调用
		//获取类的模板Class
		try {
			Class cls = Class.forName("com.neusoft.liduan.chess.Chess");
			Object obj = cls.newInstance();//创建对象
			System.out.println(obj);
//			Chess c = (Chess) obj;
//			c.setName("che");
//			System.out.println(obj);
			
			Field fname = cls.getDeclaredField("name");
			//强制开启私有属性的访问权限
			fname.setAccessible(true);
			fname.set(obj, "ma");
			System.out.println(fname.get(obj));//java.lang.IllegalAccessException: Class com.neusoft.liduan.d0927.反射 can not access a member of class com.neusoft.liduan.chess.Chess with modifiers "private"
			
			//获取所有属性
//			Field[] fields = cls.getDeclaredFields();
//			for (int i = 0; i < fields.length; i++) {
//				System.out.println(fields[i].getType());
//				System.out.println(fields[i].getName());
//			}
			
			//方法
			Method mgetName = cls.getDeclaredMethod("getName");
			Method msetName = cls.getDeclaredMethod("setName", String.class);
			msetName.invoke(obj, "xiang");
			System.out.println(mgetName.invoke(obj));
			
			//构造方法
			Constructor constructor = cls.getConstructor(String.class, Point.class, int.class);
//			cls.getConstructors();
			Object instance = constructor.newInstance("boss", new Point(5, 1), 0);
			System.out.println(instance);
			//使用反射拼接如下字符串
			//insert into ums_admin(id, username, password, icon, email, nick_name, note, create_time, login_time, status) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
